﻿using Caliburn.Micro;
using LiveChartsCore.SkiaSharpView;
using MCPlatform.Builder.WorkStation.Robot;
using MCPlatform.Builder.WorkStation.StationEvents;
using MCPlatform.Communicate.TcpIp;
using MCPlatform.Models;
using MCPlatform.Models.Motions;
using MCPlatform.MotionLib.Base;
using MCPlatform.MotionLib.Base.AssitantClass;
using MCPlatform.MotionLib.Base.AssitantClass.Exceptions;
using MCPlatform.Shared.Enums;
using MCPlatform.UI.Components;
using MCPlatform.UI.Controls.Models;
using MCPlatform.UI.Controls.Views;
using MCPlatform.UI.Controls.Views.MotionControl;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json.Linq;
using Panuon.WPF.UI;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data.OleDb;
using System.Diagnostics;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;

namespace MCPlatform.Builder.WorkStation
{
    public abstract class WorkStationBase : ViewModelBase, IStation
    {
        #region Fields
     

        protected CancellationToken cancellationToken;

        protected ManualResetEvent waitInputEvent = new ManualResetEvent(true);

        protected Dictionary<string, double> AxesPausePosition = new Dictionary<string, double>();

        protected Dictionary<string, bool> ValvesPauseStatus = new Dictionary<string, bool>();

        protected Dictionary<string, RobotPositionModel> RobotsPauseStatus = new Dictionary<string, RobotPositionModel>();

        #endregion

        #region Properties

        public bool IsClear { get; set; }


        public bool IsShield 
        {
            get => _isShield;
            set
            {
                Set(ref _isShield,value);
               
                if (value)
                {
                    EventAggregator.Unsubscribe(this);
                }
                else
                {
                    EventAggregator.SubscribeOnUIThread(this);
                }
            } 
        }
        private bool _isShield;


        public CancellationTokenSource CancellationTokenSource
        {
            get { return _CancellationTokenSource; }

            set
            {
                _CancellationTokenSource = value;
                cancellationToken = _CancellationTokenSource.Token;
            }
        } 

        private CancellationTokenSource _CancellationTokenSource = new CancellationTokenSource();
        public string StationName { get; set; } = string.Empty;

        public string StationKey { get; set; } = string.Empty;
        public WorkStationModel WorkStationModel 
        {
            get { return _WorkStationModel; }
            set 
            {
                _WorkStationModel = value;
                CylinderModels = value.CylinderModels;
                AxisModels = value.AxisModels;
                CoordinateModels = value.CoordinateModels;
                IOModels = value.IOModels;
                PointSettingModels = value.PointSettingModels;
                RobotModels = value.RobotModels;
                StationName = value.WorkStationName;
                StationKey = value.WorkStationKey;
                LogModel.StationName = value.WorkStationName;
                LogModel.RowNumber = value.WorkStationID;
            }
        } 
        private WorkStationModel _WorkStationModel = new WorkStationModel();
        public ObservableCollection<CylinderModel> CylinderModels { get; set; }= new ObservableCollection<CylinderModel>();
        public ObservableCollection<AxisModel> AxisModels { get; set; } = new ObservableCollection<AxisModel>();

        public ObservableCollection<CoordinateModel> CoordinateModels { get; set; } = new ObservableCollection<CoordinateModel>();

        public ObservableCollection<IOModel> IOModels { get; set; } = new ObservableCollection<IOModel>();

        public ObservableCollection<PointSettingModel> PointSettingModels { get; set; } = new ObservableCollection<PointSettingModel> ();

        public ObservableCollection<RobotModel> RobotModels { get; set; } = new ObservableCollection<RobotModel> ();

      

        public ManualResetEvent PauseEventSource { get; set; } = new ManualResetEvent (true);

        public ManualResetEvent SingleStepCompleteEvent { get; set; } = new ManualResetEvent(true);


        public LogModel LogModel 
        { 
            get => _LogModel;
            set 
            { 
                Set(ref _LogModel, value);
                if (value != null)
                {
                    //如果状态是中断的，把初始化完成信号置为false
                    if (value.Status == WorkStationStatus.Aborted)
                    {
                        IsInitial = false;
                         Stop().GetAwaiter().GetResult();
                    }
                    else if (value.Status == WorkStationStatus.Idle)
                    {
                        IsInitial = true;
                    }

                }
            }
        }
        private LogModel _LogModel = new LogModel();


        public bool IsInitial { get => _IsInitial; set => Set(ref _IsInitial, value); }
        private bool _IsInitial;

        public bool IsReady
        {
            get => isReady;
            set
            {
                Set(ref isReady, value);
                LogModel.IsReady = value;

            }
        }
        private bool isReady = false;

        public bool IsDone
        {
            get => isDone;
            set
            {
                Set(ref isDone, value);
                LogModel.IsDone = value;
            }
        }
        private bool isDone = false;

       

        public bool IsStepMode
        {
            get
            {
                if (AutomaticSubMode is Shared.Enums.Modes.AutomaticSubMode.SingleStep)
                {
                    return true;
                }
                return false; 
            }
            set
            {
                _isStepMode = value; 
            }
        }
        private bool _isStepMode;


        #endregion

        #region Event

        //public event Action<object>? ReadyEvent;

        //public event Action<object>? DoneEvent;

        public event Func<string,MessageBoxResult>? RetryEvent;

        public static event System.Action? PauseEvent;

        public static event System.Action<string?,bool>? StopEvent;

      

        #endregion

        #region Event Trigger
        public async void ReadyEventTrigger(object o, params EventBase[]? request)
        {
            PauseEventSource.WaitOne();

            IsReady = true;
            IsDone = false;
           // ReadyEvent?.Invoke(o);

            if (request != null)
            {
                List<Task> tasks = new List<Task>();
                foreach (var e in request)
                {
                    if (e.MessageType != MessageType.NotifyTrayEmpty)
                    {
                        e.MessageType = MessageType.NotifyReady;
                    }
                    
                    tasks.Add(SendAsync(e));
                    //await Send(e);
                }
                await Task.WhenAll(tasks);
            }
        }
            
        public async void DoneEventTrigger(object o,params EventBase[]? request)
        {
            PauseEventSource.WaitOne();
            IsDone = true;
            IsReady = false;
           // DoneEvent?.Invoke(o);
            if (request != null)
            {
                List<Task> tasks = new List<Task>();
                foreach (var e in request)
                {
                    e.MessageType = MessageType.NotifyDone;
                    tasks.Add(SendAsync(e));
                    //await Send(e);
                }
                await Task.WhenAll(tasks);


            }
        }

        public MessageBoxResult RetryEventTrigger(string info)
        {
            PauseEvent?.Invoke();
           var result =  RetryEvent?.Invoke(info);

            if (result is null)
            {
                return MessageBoxResult.None;
            }
            return (MessageBoxResult)result;
        }


        public void StopTrigger(string? stopMessage = null,bool isSetAbortedStatus = true)
        {
            StopEvent?.Invoke(stopMessage, isSetAbortedStatus);
        }


       

        #endregion

        #region CTOR

        public WorkStationBase()
        {
            cancellationToken = CancellationTokenSource.Token;
            EventAggregator.SubscribeOnUIThread(this);
        }
        #endregion


        #region Methods

        /// <summary>
        /// 当前移动是否安全判断条件
        /// </summary>
        /// <returns></returns>
        public abstract Task<bool> IsSaftyToMove();


        /// <summary>
        /// 判断轴当前是否准备好
        /// </summary>
        /// <returns></returns>
        public  (bool, short, string) IsAxisReady(IMotion? motion = null)
        {
            (bool, short, string) res = (true, 0, "Check done");
            try
            {
                foreach (var axis in AxisModels)
                {
                    if (axis.MotionEntity != null)
                    {
                        if (axis.MotionEntity.IsEMG)
                        {

                            throw new MyAxisException($"{axis.MotionEntity.ControlName} Is EMG");

                        }
                        else if (axis.MotionEntity.IsError)
                        {

                            throw new MyAxisException($"{axis.MotionEntity.ControlName} Is Error");

                        }
                        else if (motion != null )
                        {

                            //if(motion.ControlName == axis.MotionEntity.ControlName && axis.MotionEntity.IsMoving)
                            //{
                            //    throw new MyAxisException($"{axis.MotionEntity.ControlName} Is Busy");
                            //}                                                     

                        }
                        else if (!axis.MotionEntity.IsEnabled)
                        {
                            axis.MotionEntity.Enable();
                        }

                        if (!res.Item1)
                        {
                            return res;
                        }
                    }

                   

                }
            }
            catch (Exception)
            {

                throw;
            }
          
            return res;
        }


        public void IsMovingPosOutofRange(IMotion axis,PointSettingModel point,bool isAbsMove = true)
        {
            
            try
            {
                if (isAbsMove)
                {
                    if (point.Parameter >= axis.AxisConfig.SPLimit)
                    {
                        throw new MyAxisException($"{axis.ControlName} Abs Moving Out of PLimit");
                    }
                    else if (point.Parameter <= axis.AxisConfig.SNLimit)
                    {
                        throw new MyAxisException($"{axis.ControlName} Abs Moving Out of NLimit");
                    }
                }
                else
                {
                    if (point.Parameter + axis.ActualPosition >= axis.AxisConfig.SPLimit)
                    {
                        throw new MyAxisException($"{axis.ControlName} Rel Moving Out of PLimit");
                    }
                    else if (point.Parameter + axis.ActualPosition <= axis.AxisConfig.SNLimit)
                    {
                        throw new MyAxisException($"{axis.ControlName} Rel Moving Out of NLimit");
                    }
                }
               
            }
            catch (Exception)
            {

                throw;
            }
           
           
        }


        public void IsMovingPosOutofRange(IMotion axis, double point, bool isAbsMove = true)
        {

            try
            {
                if (isAbsMove)
                {
                    if (point >= axis.AxisConfig.SPLimit)
                    {
                        throw new MyAxisException($"{axis.ControlName} Abs Moving Out of PLimit");
                    }
                    else if (point <= axis.AxisConfig.SNLimit)
                    {
                        throw new MyAxisException($"{axis.ControlName} Abs Moving Out of NLimit");
                    }
                }
                else
                {
                    if (point + axis.ActualPosition >= axis.AxisConfig.SPLimit)
                    {
                        throw new MyAxisException($"{axis.ControlName} Rel Moving Out of PLimit");
                    }
                    else if (point + axis.ActualPosition <= axis.AxisConfig.SNLimit)
                    {
                        throw new MyAxisException($"{axis.ControlName} Rel Moving Out of NLimit");
                    }
                }

            }
            catch (Exception)
            {

                throw;
            }


        }

        public async Task<(bool, short, string)> CheckStationStatus()
        {
            (bool, short, string) res = (true, 0, "Check done");
            try
            {
                if (LogModel.Status == WorkStationStatus.Aborted)
                {
                    res = (false, 0, "请先复位错误！");
                 
                    throw new Exception("请先复位错误！");
                }
                else if (LogModel.Status == WorkStationStatus.Stopped)
                {
                    res = (false, 0, "请先初始化！");
                  
                    throw new Exception("请先初始化！");
                }
            }
            catch (Exception ex)
            {
                MessageBoxX.Show($"{ex.Message}");
                throw;
            }
            await Task.Delay(1);
            return res;
        }

        /// <summary>
        /// 工站全部轴使能
        /// </summary>
        /// <returns></returns>
        public (bool,short,string) SetAllAxisEnable()
        {
            LogModel.LogInfo = $"全部轴使能中";
            if (AxisModels.Count <=0)
            {
                LogModel.LogInfo = $"全部轴使能：完成";
                LogModel.Status = WorkStationStatus.Stopped;
                return (true, 0, "Enable Done");
            }
           
            foreach (var axis in AxisModels)
            {
                if (axis.MotionEntity!=null)
                {
                    var res = axis.MotionEntity.Enable();
                    if (!res.Equals(0))
                    {
                        LogModel.LogInfo = $"使能失败：errorID:{res}，{axis.MotionEntity.ControlName}Enable error";
                        return (false, res, $"{axis.MotionEntity.ControlName}Enable error, errorID:{res}");
                    }
                }
              
            }
            LogModel.LogInfo = $"全部轴使能：完成";
            LogModel.Status = WorkStationStatus.Stopped;
            return (true,0, "Enable Done");
        }

        /// <summary>
        /// 工站全部轴回原
        /// </summary>
        /// <returns></returns>
        public async Task<(bool,short, string)> SetAllAxisHome(bool isOrder=false)
        {
            LogModel.LogInfo = $"全部轴回原";

            (bool, short, string) res = (true, 0, "All Home done");
            //1.先判断数量是否又轴，没有直接返回
            if (AxisModels.Count <= 0)
            {
                LogModel.LogInfo = $"全部轴回原：完成";
                LogModel.Status = WorkStationStatus.Idle;
                return res;
            }
            //2.使能
            res = SetAllAxisEnable();
            if (!res.Item1)
            {
                return res;
            }

            //3.判断是否需要按顺序回原还是一起回原
            List<Task<(bool, short, string)>> tasks = new List<Task<(bool, short, string)>>();

            try
            {
                await Task.Run(async () =>
                {
                   
                    LogModel.LogInfo = "开始回原！";

                    foreach (var axis in AxisModels)
                    {
                        //检测是否需要暂停
                        PauseEventSource.WaitOne();

                        if (axis.MotionEntity != null)
                        {
                            if (isOrder)
                            {
                                res = await axis.MotionEntity.HomeMoveAsync(CancellationTokenSource.Token,PauseEventSource);

                                if (!res.Item2.Equals(0))
                                {
                                    LogModel.LogInfo = $"回原失败：errorID:{res.Item2}，{axis.MotionEntity.ControlName}{res.Item3}";
                                    LogModel.Status = WorkStationStatus.Aborted;
                                    return;
                                }
                            }
                            else
                            {
                                tasks.Add(axis.MotionEntity.HomeMoveAsync(CancellationTokenSource.Token, PauseEventSource));
                            }
                        }

                        
                    }

                }, cancellationToken);


                if (isOrder)
                {
                    //等待全部回原完成
                    var results = await Task.WhenAll(tasks);

                    if (results.Any(result => !result.Item1 || result.Item2 != 0))
                    {
                        // 如果有任何一个任务失败，返回错误信息
                        var failedResult = results.First(result => !result.Item1 || result.Item2 != 0);
                        LogModel.LogInfo = $"回原失败：errorID:{failedResult.Item2}，{failedResult.Item3}";
                        LogModel.Status = WorkStationStatus.Aborted;
                        res = (false, failedResult.Item2, failedResult.Item3);
                    }
                }

            }
            catch (Exception ex)
            {
                if (ex is OperationCanceledException)
                {
                    throw;
                }
               
            }     
            //4.回原完成
            LogModel.LogInfo = $"全部轴回原：完成";
            LogModel.Status = WorkStationStatus.Idle;
            return res;
        }

        /// <summary>
        /// 全部轴停止
        /// </summary>
        /// <returns></returns>
        public (bool, short, string) SetAllAxisStop()
        {
            //1.判断轴是否有
           // LogModel.LogInfo = $"全部轴停止";
            if (AxisModels.Count <= 0)
            {
              //  LogModel.LogInfo = $"全部轴全部轴停止：完成";
                LogModel.Status = WorkStationStatus.Aborted;
                return (true, 0, "Stop Done");
            }
            //2.停止全部轴         
           // List<Task<short>> tasks = new List<Task<short>>();
            foreach (var axis in AxisModels)
            {
                axis?.MotionEntity?.StopMove();
                //tasks.Add(Task.Run(() => axis.MotionEntity.StopMove()));            
            }
            //var results = await Task.WhenAll(tasks);
            //if (results.Any(result => result != 0))
            //{
            //    // 如果有任何一个任务失败，返回错误信息
            //    var failedResult = results.First(result =>result!= 0);
            //    LogModel.LogInfo = $"轴停止失败：errorID:{failedResult}";
            //    LogModel.Status = WorkStationStatus.Aborted;
            //    return (false, failedResult, "Stop Failed");
            //}

            //3.停止完成
          //  LogModel.LogInfo = $"全部轴全部轴停止：完成";
            LogModel.Status = WorkStationStatus.Aborted;
            return (true, 0, "Stop Done");
        }

        /// <summary>
        /// 全部轴暂停
        /// </summary>
        public void SetAllAxisPause()
        {
                  
            foreach (var axis in AxisModels)
            {
                axis?.MotionEntity?.PauseMove();
                            
            }

            foreach (var coordinate in CoordinateModels)
            {
                if (coordinate != null && coordinate.ImputationEntity != null && coordinate.ImputationEntity.IsImpBusy)
                {
                    coordinate?.ImputationEntity?.ContiPauseList();

                }
                

            }


        }

        /// <summary>
        /// 全部轴暂停恢复运行
        /// </summary>
        public async Task SetAllAxisResume()
        {
           
            List<Task> tasks = new List<Task>();
            foreach (var axis in AxisModels)
            {
                if (axis!=null && axis.MotionEntity!=null)
                {
                    tasks.Add(axis.MotionEntity.Resume(this.cancellationToken));
                   // axis.MotionEntity.Resume(this.cancellationToken);
                }


            }

            //坐标系恢复插补
            foreach (var coordinate in CoordinateModels)
            {
                if (coordinate != null && coordinate.ImputationEntity != null && coordinate.ImputationEntity.IsImpPasue)
                {
                    coordinate.ImputationEntity.ContiStartList();                   
                   
                }
                

            }
            await Task.WhenAll(tasks);

        }

        /// <summary>
        /// 全部机器人暂停
        /// </summary>
        public async Task SetAllRobotPause()
        {

            foreach (var robotModel in RobotModels)
            {
                await robotModel.Robot.PauseAsync();
            }


        }


        /// <summary>
        /// 全部机器人恢复运行
        /// </summary>
        /// <returns></returns>
        public async Task SetAllRobotResume()
        {

            foreach (var robotModel in RobotModels)
            {
                await robotModel.Robot.ResumnAsync();
            }


        }



        /// <summary>
        /// 全部气缸回原位
        /// </summary>
        /// <param name="isOrder"></param>
        /// <returns></returns>
        public async Task<(bool, short, string)> SetAllValvesBasing(bool isOrder = false)
        {
            LogModel.LogInfo = $"{StationName}全部气缸回原位";
            PauseEventSource.WaitOne();

            try
            {
                if (CylinderModels.Count <= 0)
                {
                    return (true, 0, "Valves Based Done");
                }

                List<Task<bool>> tasks = new List<Task<bool>>();

                foreach (var valve in CylinderModels)
                {
                    if (valve.ValveEntity is null)
                    {
                        LogModel.LogInfo = $"{StationName}气缸回原位失败：errorID:1，valve is null";
                        LogModel.Status = WorkStationStatus.Aborted;
                        throw new ValveException($"{StationName}气缸回原位失败：errorID:1，valve is null");
                    }

                    if (isOrder)
                    {
                        bool result = await valve.ValveEntity.BasingAsync();
                        if (!result)
                        {
                            LogModel.LogInfo = $"气缸回原位失败：errorID:2，{valve.ValveEntity.ValveName} Basing Error";
                            LogModel.Status = WorkStationStatus.Aborted;
                            throw new ValveException($"{valve.ValveEntity.ValveName} Basing Error");
                        }
                    }
                    else
                    {
                        tasks.Add(valve.ValveEntity.BasingAsync());
                    }
                }

                if (!isOrder)
                {
                    await Task.WhenAll(tasks);
                    if (tasks.Any(t => !t.Result))
                    {
                        int index = tasks.FindIndex(t => !t.Result);
                        Logger.Error($"{CylinderModels[index]?.ValveEntity?.ValveName}气缸回原位m失败：errorID:2, Working Error");
                        LogModel.LogInfo = $"{CylinderModels[index]?.ValveEntity?.ValveName}气缸回原位失败：errorID:2, Basing Error";
                        LogModel.Status = WorkStationStatus.Aborted;
                        throw new ValveException($" Basing Error");
                    }
                }
            }
            catch (ValveException)
            {
                PauseEvent?.Invoke();
                MessageBoxResult retryRes = (MessageBoxResult)(RetryEvent?.Invoke($"全部气缸去原位超时，请检查气源后，是否重试？"))!;

                if (retryRes == MessageBoxResult.Yes)
                {
                    return (await SetAllValvesBasing(isOrder));
                }
                else if (retryRes == MessageBoxResult.No)
                {
                    await Stop();
                }
                else
                {
                    throw;
                }
            }

            LogModel.LogInfo = $"全部气缸回原位完成";
            return (true, 0, "All Based Done");
        }


        /// <summary>
        /// 全部气缸到工作位
        /// </summary>
        /// <param name="isOrder">是否按顺序</param>
        /// <returns></returns>
        public async Task<(bool, short, string)> SetAllValvesWorking(bool isOrder = false)
        {
            try
            {
                PauseEventSource.WaitOne();
                LogModel.LogInfo = $"全部气缸到工作位";

                if (CylinderModels.Count <= 0)
                {
                    return (true, 0, "Valves Worked Done");
                }

                List<Task<bool>> tasks = new List<Task<bool>>();
                foreach (var valve in CylinderModels)
                {
                    if (valve.ValveEntity is null)
                    {
                        LogModel.LogInfo = $"气缸到工作位失败：errorID:1，valve is null";
                        LogModel.Status = WorkStationStatus.Aborted;

                        return (false, 1, $"valve is null");
                    }

                    bool result = false;

                    if (isOrder)
                    {
                        result = await valve.ValveEntity.WorkingAsync();
                        if (!result)
                        {
                            LogModel.LogInfo = $"气缸到工作位失败：errorID:2，{valve.ValveEntity.ValveName} Working Error";
                            LogModel.Status = WorkStationStatus.Aborted;
                            return (false, 2, $"{valve.ValveEntity.ValveName} Working Error");
                        }
                    }
                    else
                    {
                        tasks.Add(valve.ValveEntity.WorkingAsync());
                    }

                }

                if (!isOrder)
                {
                    var results = await Task.WhenAll(tasks);
                    if (results.Any(res => !res))
                    {
                        int index = tasks.FindIndex(t => !t.Result);
                        var failRes = results.First(res => !res);
                        Logger.Error($"{CylinderModels[index]?.ValveEntity?.ValveName}气缸到工作位失败：errorID:2, Working Error");
                        LogModel.LogInfo = $"{CylinderModels[index]?.ValveEntity?.ValveName}气缸到工作位失败：errorID:2, Working Error";
                        LogModel.Status = WorkStationStatus.Aborted;
                        return (false, 2, $"Working Error");
                    }
                }
              
            }
            catch (ValveException)
            {
                PauseEvent?.Invoke();
                var retryRes = (MessageBoxResult)(RetryEvent?.Invoke($"全部气缸去工作位超时，请检查气源后，是否重试？"))!;

                if (retryRes == MessageBoxResult.Yes)
                {
                   return await SetAllValvesWorking();
                }
                else if (retryRes == MessageBoxResult.No)
                {
                    await Stop();
                }
                else
                {
                    throw;
                }
            }
            catch (Exception)
            {

                throw;
            }

            LogModel.LogInfo = $"全部气缸到工作位完成";
            return (true, 0, "All Worked Done");

        }


        public async Task<(bool, short, string)> SetMultipleValvesBasingAsync(params IValve[] valves)
        {
            LogModel.LogInfo = $"{StationName}全部气缸回原位";

            try
            {
                PauseEventSource.WaitOne();

                if (CylinderModels.Count <= 0)
                {
                    return (true, 0, "Valves Based Done");
                }

                List<Task<bool>> tasks = new List<Task<bool>>();

                foreach (var valve in valves)
                {
                    tasks.Add(valve.BasingAsync());
                }

                await Task.WhenAll(tasks);
                if (tasks.Any(t => !t.Result))
                {
                    int index = tasks.FindIndex(t => !t.Result);
                    Logger.Error($"{valves[index]?.ValveName}气缸回原位失败：errorID:2, Working Error");
                    LogModel.LogInfo = $"{valves[index].ValveName}气缸回原位失败：errorID:2, Basing Error";
                    LogModel.Status = WorkStationStatus.Aborted;
                    throw new ValveException($" Basing Error");
                }
            }
            catch (ValveException)
            {
                PauseEvent?.Invoke();
                MessageBoxResult retryRes = (MessageBoxResult)(RetryEvent?.Invoke($"全部气缸去原位超时，请检查气源后，是否重试？"))!;              
                if (retryRes == MessageBoxResult.Yes)
                {
                    return (await SetMultipleValvesBasingAsync(valves));
                }
                else if (retryRes == MessageBoxResult.No)
                {
                    await Stop();
                }
                else
                {
                    throw;
                }
            }

            LogModel.LogInfo = $"多个气缸同时回原位完成";
            return (true, 0, "All Based Done");
        }


        public async Task<(bool, short, string)> SetMultipleValvesWorkingAsync(params IValve[] valves)
        {
            try
            {
                PauseEventSource.WaitOne();
                LogModel.LogInfo = $"全部气缸到工作位";

                if (CylinderModels.Count <= 0)
                {
                    return (true, 0, "Valves Worked Done");
                }

                List<Task<bool>> tasks = new List<Task<bool>>();
                foreach (var valve in valves)
                {
                    if (valve is null)
                    {
                        LogModel.LogInfo = $"气缸到工作位失败：errorID:1，valve is null";
                        LogModel.Status = WorkStationStatus.Aborted;

                        return (false, 1, $"valve is null");
                    }

                   

                    tasks.Add(valve.WorkingAsync());

                }

                var results = await Task.WhenAll(tasks);
                if (results.Any(res => !res))
                {
                    int index = tasks.FindIndex(t => !t.Result);
                    Logger.Error($"{valves[index]?.ValveName}气缸到工作位失败：errorID:2, Working Error");
                    LogModel.LogInfo = $"{valves[index]?.ValveName}气缸到工作位失败：errorID:2, Working Error";
                    LogModel.Status = WorkStationStatus.Aborted;
                    return (false, 2, $"Working Error");
                }

            }
            catch (ValveException)
            {
                PauseEvent?.Invoke();
                var retryRes = (MessageBoxResult)(RetryEvent?.Invoke($"多个气缸去工作位超时，请检查气源后，是否重试？"))!;

                if (retryRes == MessageBoxResult.Yes)
                {
                    return await SetMultipleValvesWorkingAsync(valves);
                }
                else if (retryRes == MessageBoxResult.No)
                {
                    await Stop();
                }
                else
                {
                    throw;
                }
            }
            catch (Exception)
            {

                throw;
            }

            LogModel.LogInfo = $"多个气缸到工作位完成";
            return (true, 0, "All Worked Done");

        }

        /// <summary>
        /// 等待某个输入信号输入
        /// </summary>
        /// <param name="signal">信号</param>
        /// <param name="timeOut">超时时间</param>
        /// <param name="delay">延迟时间</param>
        /// <returns></returns>
        /// 
        public async Task<(bool, short, string)> WaitInputSignalIn(IIO signal,bool isForJudge = false, int timeOut = 10000, int delay = 0,IMotion? motion = null)
        {
            try
            {
                LogModel.LogInfo = $"等待{signal.IOName}输入信号";
               
                var stopwatch = Stopwatch.StartNew();

                while (!signal.Value && stopwatch.ElapsedMilliseconds < timeOut && !cancellationToken.IsCancellationRequested)
                {
                   
                    // 检查是否暂停
                    if (!waitInputEvent.WaitOne(0))
                    {
                        // 如果计时器在运行，则停止计时
                        if (stopwatch.IsRunning)
                        {
                            stopwatch.Stop();
                        }
                        
                    }

                    else
                    {
                        // 如果计时器未运行，则开始计时
                        if (!stopwatch.IsRunning)
                        {
                            stopwatch.Start();
                        }
                    }

                    // 等待短暂的延迟，避免过于频繁的检查
                    await Task.Delay(1);
                }

                // 如果超时或被取消，进行相应处理
                if (!signal.Value)
                {
                    stopwatch.Stop();
                    LogModel.LogInfo = $"{signal.IOName}输入信号超时！";
                    Logger.Error($"{signal.IOName}输入信号超时！");
                    if (isForJudge)
                    {
                        return (false, -1, "TimeOut");
                    }

                    PauseEvent?.Invoke();
                    motion?.StopMove();

                    while (true)
                    {
                        var retryRes = (MessageBoxResult)(RetryEvent?.Invoke($"等待{signal.IOName}输入信号超时，超时时间{timeOut}ms，地址：I{signal.Address}，是否重试？"))!;

                        if (retryRes == MessageBoxResult.Yes)
                        {
                            // 重试等待输入信号
                            LogModel.LogInfo = $"{signal.IOName}输入信号超时，重试中...";
                            stopwatch.Restart();
                            while (!signal.Value && stopwatch.ElapsedMilliseconds < timeOut && !cancellationToken.IsCancellationRequested)
                            {
                                await Task.Delay(1);
                            }
                            if (signal.Value)
                            {
                                LogModel.LogInfo = $"{signal.IOName}输入信号到达！";
                                break;
                            }
                        }
                        else if (retryRes == MessageBoxResult.No)
                        {
                            LogModel.LogInfo = $"{signal.IOName}输入信号超时，放弃重试。";
                            StopTrigger(isSetAbortedStatus: false);
                            break;
                        }
                        else
                        {
                            // 抛出超时异常
                            throw new TimeOutException($"等待{signal.IOName}输入信号超时，地址：I{signal.Address}");
                        }
                    }

                    await Task.Delay(delay);
                    LogModel.LogInfo = $"{signal.IOName}输入信号到达！";
                    return (true, 0, "signal In");
                }

                await Task.Delay(delay);
                LogModel.LogInfo = $"{signal.IOName}输入信号到达！";
                return (true, 0, "signal In");
            }
            catch (Exception)
            {

                throw;
            }
            finally 
            {
                
            };
            
        }

        public async Task<(bool, short, string)> HomeAsync(IMotion axis)
        {

            (bool, short, string) res = (true, 0, "done");
         
            try
            {
                await IsSaftyToMove();
                res = IsAxisReady(axis);
              
                await Task.Run(async () =>
                {
                    try
                    {
                        PauseEventSource.WaitOne();
                        LogModel.LogInfo = $"{axis.ControlName}开始回原";

                        res = await axis.HomeMoveAsync(CancellationTokenSource.Token, PauseEventSource);
                    }
                    catch (TaskCanceledException)
                    {

                        throw;
                    }
                   

                }, cancellationToken);

                PauseEventSource.WaitOne();
                if (!res.Item1)
                {
                    SetAllAxisStop();
                    LogModel.LogInfo = $"{res.Item3}";
                    LogModel.Status = WorkStationStatus.Aborted;
                    throw new MyAxisException(res.Item3);
                }

                LogModel.LogInfo = $"{axis.ControlName}回原完成!";
            }
            catch (OperationCanceledException)
            {
                // 取消请求被捕获，可以在这里进行相应的清理工作
                LogModel.LogInfo = $"{axis.ControlName}回原被中断!";
                LogModel.Status = WorkStationStatus.Aborted;
                throw;
            }
            catch (MyAxisException ex)
            {
                LogModel.LogInfo = $"{ex.Message}";
                LogModel.Status = WorkStationStatus.Aborted;
                throw;
            }
            catch (Exception)
            {
                LogModel.LogInfo = $"{axis.ControlName}回原异常!";
                LogModel.Status = WorkStationStatus.Aborted;
                throw;
            }
        
            return res;

        }

        public async Task<(bool, short, string)> MultiAbsMoveAsync(IMotion[] axises,params PointSettingModel[] points)
        {
            StepPause();

            (bool, short, string) res = (true, 0, "done");
            try
            {
                if (axises.Length != points.Length)
                {
                    throw new ArgumentException();
                }

                Task[] task = new Task[axises.Length];
                for (int i = 0;i<axises.Length; i++)
                {
                    task[i] = AbsMoveAsync(axises[i], points[i]);
                }

                await Task.WhenAll(task);

                return res;
            }
            catch (Exception)
            {

                throw;
            }
        }

        public async Task<(bool, short, string)> MultiAbsMoveAsync(IMotion[] axises, params double[] points)
        {
            StepPause();

            (bool, short, string) res = (true, 0, "done");
            try
            {
                if (axises.Length != points.Length)
                {
                    throw new ArgumentException();
                }

                Task[] task = new Task[axises.Length];
                for (int i = 0; i < axises.Length; i++)
                {
                    task[i] = AbsMoveAsync(axises[i], points[i]);
                }

                await Task.WhenAll(task);

                return res;
            }
            catch (Exception)
            {

                throw;
            }
        }

        public async Task<(bool, short, string)> MultiRelMoveAsync(IMotion[] axises, params PointSettingModel[] points)
        {
            StepPause();

            (bool, short, string) res = (true, 0, "done");
            try
            {
                if (axises.Length != points.Length)
                {
                    throw new ArgumentException();
                }

                Task[] task = new Task[axises.Length];
                for (int i = 0; i < axises.Length; i++)
                {
                    task[i] = RelMoveAsync(axises[i], points[i]);
                }

                await Task.WhenAll(task);

                return res;
            }
            catch (Exception)
            {

                throw;
            }
        }

        public async Task<(bool, short, string)> MultiRelMoveAsync(IMotion[] axises, params double[] points)
        {
            StepPause();

            (bool, short, string) res = (true, 0, "done");
            try
            {
                if (axises.Length != points.Length)
                {
                    throw new ArgumentException();
                }

                Task[] task = new Task[axises.Length];
                for (int i = 0; i < axises.Length; i++)
                {
                    task[i] = RelMoveAsync(axises[i], points[i]);
                }

                await Task.WhenAll(task);

                return res;
            }
            catch (Exception)
            {

                throw;
            }
        }

        public async Task<(bool, short, string)> ImpRelMoveAsync(IImputation axises, params PointSettingModel[] points)
        {
            StepPause();

            (bool, short, string) res = (true, 0, "done");

            try
            {
                await IsSaftyToMove();
               
              //  IsMovingPosOutofRange(axis, point, false);

                await Task.Run(async () =>
                {
                    try
                    {
                        PauseEventSource.WaitOne();
                        LogModel.LogInfo = $"{axises.ControlName}开始相对移动：{axises.ControlName}";

                        List<double> targetPoints = new List<double>();
                        foreach (var point in points)
                        {
                            targetPoints.Add(point.Parameter);
                        }

                        res = await axises.ImpLineRelMoveAsync(targetPoints.ToArray(),cancellationToken,PauseEventSource);
                        PauseEventSource.WaitOne();
                    }
                    catch (TaskCanceledException)
                    {
                        // 在这里处理取消操作，如果需要
                        LogModel.LogInfo = $"{axises.ControlName}相对移动被中断!";
                        LogModel.Status = WorkStationStatus.Aborted;
                        throw; // 重新抛出异常以将其传播到Task.Run之外
                    }


                }, cancellationToken);

                LogModel.LogInfo = $"{axises.ControlName}相对移动：{axises.ControlName}";
            }
            catch (OperationCanceledException)
            {
                // 取消请求被捕获，可以在这里进行相应的清理工作
                LogModel.LogInfo = $"{axises.ControlName}相对移动被中断!";
                LogModel.Status = WorkStationStatus.Aborted;
                throw;
            }
            catch (MyAxisException ex)
            {
                LogModel.LogInfo = $"{ex.Message}";
                LogModel.Status = WorkStationStatus.Aborted;
                throw;
            }
            catch (Exception)
            {
                LogModel.LogInfo = $"{axises.ControlName}相对移动异常!";
                LogModel.Status = WorkStationStatus.Aborted;
                throw;
            }

            return res;

        }
        public async Task<(bool, short, string)> ImpAbsMoveAsync(IImputation axises, params PointSettingModel[] points)
        {
            StepPause();

            (bool, short, string) res = (true, 0, "done");

            try
            {
                await IsSaftyToMove();

                //  IsMovingPosOutofRange(axis, point, false);

                await Task.Run(async () =>
                {
                    try
                    {
                        PauseEventSource.WaitOne();
                        LogModel.LogInfo = $"{axises.ControlName}开始绝对移动：{axises.ControlName}";

                        List<double> targetPoints = new List<double>();
                        foreach (var point in points)
                        {
                            targetPoints.Add(point.Parameter);
                        }

                        res = await axises.ImpLineAbsMoveAsync(targetPoints.ToArray(), cancellationToken, PauseEventSource);
                        PauseEventSource.WaitOne();
                    }
                    catch (TaskCanceledException)
                    {
                        // 在这里处理取消操作，如果需要
                        LogModel.LogInfo = $"{axises.ControlName}绝对移动被中断!";
                        LogModel.Status = WorkStationStatus.Aborted;
                        throw; // 重新抛出异常以将其传播到Task.Run之外
                    }


                }, cancellationToken);

                LogModel.LogInfo = $"{axises.ControlName}绝对移动：{axises.ControlName}";
            }
            catch (OperationCanceledException)
            {
                // 取消请求被捕获，可以在这里进行相应的清理工作
                LogModel.LogInfo = $"{axises.ControlName}绝对移动被中断!";
                LogModel.Status = WorkStationStatus.Aborted;
                throw;
            }
            catch (MyAxisException ex)
            {
                LogModel.LogInfo = $"{ex.Message}";
                LogModel.Status = WorkStationStatus.Aborted;
                throw;
            }
            catch (Exception)
            {
                LogModel.LogInfo = $"{axises.ControlName}绝对移动异常!";
                LogModel.Status = WorkStationStatus.Aborted;
                throw;
            }

            return res;

        }

        public async Task<(bool, short, string)> ImpAbsMoveAsync(IImputation axises, params double[] points)
        {
            StepPause();

            (bool, short, string) res = (true, 0, "done");

            try
            {
                await IsSaftyToMove();

                //  IsMovingPosOutofRange(axis, point, false);

                await Task.Run(async () =>
                {
                    try
                    {
                        PauseEventSource.WaitOne();
                        LogModel.LogInfo = $"{axises.ControlName}开始绝对移动：{axises.ControlName}";

                        List<double> targetPoints = new List<double>();
                        foreach (var point in points)
                        {
                            targetPoints.Add(point);
                        }

                        res = await axises.ImpLineAbsMoveAsync(targetPoints.ToArray(), cancellationToken, PauseEventSource);
                    }
                    catch (TaskCanceledException)
                    {
                        // 在这里处理取消操作，如果需要
                        LogModel.LogInfo = $"{axises.ControlName}绝对移动被中断!";
                        LogModel.Status = WorkStationStatus.Aborted;
                        throw; // 重新抛出异常以将其传播到Task.Run之外
                    }


                }, cancellationToken);

                LogModel.LogInfo = $"{axises.ControlName}绝对移动：{axises.ControlName}";
            }
            catch (OperationCanceledException)
            {
                // 取消请求被捕获，可以在这里进行相应的清理工作
                LogModel.LogInfo = $"{axises.ControlName}绝对移动被中断!";
                LogModel.Status = WorkStationStatus.Aborted;
                throw;
            }
            catch (MyAxisException ex)
            {
                LogModel.LogInfo = $"{ex.Message}";
                LogModel.Status = WorkStationStatus.Aborted;
                throw;
            }
            catch (Exception)
            {
                LogModel.LogInfo = $"{axises.ControlName}绝对移动异常!";
                LogModel.Status = WorkStationStatus.Aborted;
                throw;
            }

            return res;

        }

        public async Task<(bool, short, string)> AbsMoveAsync(IMotion axis, PointSettingModel point)
        {
             StepPause();

             (bool, short, string) res = (true, 0, "done");

            try
            {
                await IsSaftyToMove();
              
                res = IsAxisReady(axis);

                IsMovingPosOutofRange(axis, point);

                await Task.Run(async () =>
                {
                    if (cancellationToken.IsCancellationRequested)
                    {
                        cancellationToken.ThrowIfCancellationRequested();
                    }

                    PauseEventSource.WaitOne();
                    LogModel.LogInfo = $"{axis.ControlName}开始绝对移动至：{point.ControlName}";

                    res = await axis.AbsMoveAsync(point.Parameter, cancellationToken,PauseEventSource);

                }, cancellationToken);

                PauseEventSource.WaitOne();
                if (!res.Item1)
                {
                    SetAllAxisStop();
                    LogModel.LogInfo = $"{res.Item3}";
                    LogModel.Status = WorkStationStatus.Aborted;
                    throw new MyAxisException(res.Item3);
                }

                LogModel.LogInfo = $"{axis.ControlName}绝对移动至：{point.ControlName} 完成！";
            }
            catch (OperationCanceledException)
            {
                // 取消请求被捕获，可以在这里进行相应的清理工作
                LogModel.LogInfo = $"{axis.ControlName}绝对移动被中断!";
                LogModel.Status = WorkStationStatus.Aborted;
                throw;
            }
            catch (MyAxisException ex)
            {
                LogModel.LogInfo = $"{ex.Message}";
                LogModel.Status = WorkStationStatus.Aborted;
                throw;
            }
            catch (Exception)
            {
                LogModel.LogInfo = $"{axis.ControlName}绝对移动异常!";
                LogModel.Status = WorkStationStatus.Aborted;
                throw;
            }
            return res;
        }

        public async Task<(bool, short, string)> AbsMoveAsync(IMotion axis, double point)
        {
            StepPause();

            (bool, short, string) res = (true, 0, "done");

            try
            {
                await IsSaftyToMove();

                res = IsAxisReady(axis);

                IsMovingPosOutofRange(axis, point);

                await Task.Run(async () =>
                {
                    
                    if ( cancellationToken.IsCancellationRequested)
                    {                      
                        cancellationToken.ThrowIfCancellationRequested();
                    }
                  

                    PauseEventSource.WaitOne();
                    LogModel.LogInfo = $"{axis.ControlName}开始绝对移动至：{point}";

                    res = await axis.AbsMoveAsync(point, cancellationToken, PauseEventSource);

                }, cancellationToken);
                PauseEventSource.WaitOne();
                if (!res.Item1)
                {
                    SetAllAxisStop();
                    LogModel.LogInfo = $"{res.Item3}";
                    LogModel.Status = WorkStationStatus.Aborted;
                    throw new MyAxisException(res.Item3);
                }

                LogModel.LogInfo = $"{axis.ControlName}绝对移动至：{point} 完成！";
            }
            catch (OperationCanceledException)
            {
                // 取消请求被捕获，可以在这里进行相应的清理工作
                LogModel.LogInfo = $"{axis.ControlName}绝对移动被中断!";
                LogModel.Status = WorkStationStatus.Aborted;
                throw;
            }
            catch (MyAxisException ex)
            {
                LogModel.LogInfo = $"{ex.Message}";
                LogModel.Status = WorkStationStatus.Aborted;
                throw;
            }
            catch (Exception)
            {
                LogModel.LogInfo = $"{axis.ControlName}绝对移动异常!";
                LogModel.Status = WorkStationStatus.Aborted;
                throw;
            }
            return res;
        }

        public async Task<(bool, short, string)> RelMoveAsync(IMotion axis, PointSettingModel point)
        {
            StepPause();

            (bool, short, string) res = (true, 0, "done");

            try
            {
                await IsSaftyToMove();
                res = IsAxisReady(axis);

                IsMovingPosOutofRange(axis, point,false);

                await Task.Run(async () =>
                {
                    try
                    {
                        PauseEventSource.WaitOne();
                        LogModel.LogInfo = $"{axis.ControlName}开始相对移动：{point.ControlName}";

                        res = await axis.RelMoveAsync(point.Parameter, cancellationToken, PauseEventSource);
                    }
                    catch (TaskCanceledException)
                    {
                        // 在这里处理取消操作，如果需要
                        LogModel.LogInfo = $"{axis.ControlName}点动被中断!";
                        LogModel.Status = WorkStationStatus.Aborted;
                        throw; // 重新抛出异常以将其传播到Task.Run之外
                    }
                   

                }, cancellationToken);
                PauseEventSource.WaitOne();
                if (!res.Item1)
                {
                    SetAllAxisStop();
                    LogModel.LogInfo = $"{res.Item3}";
                    LogModel.Status = WorkStationStatus.Aborted;
                    throw new MyAxisException(res.Item3);
                }

                LogModel.LogInfo = $"{axis.ControlName}相对移动：{point.ControlName}";
            }
            catch (OperationCanceledException)
            {
                // 取消请求被捕获，可以在这里进行相应的清理工作
                LogModel.LogInfo = $"{axis.ControlName}相对移动被中断!";
                LogModel.Status = WorkStationStatus.Aborted;
                throw;
            }
            catch (MyAxisException ex)
            {
                LogModel.LogInfo = $"{ex.Message}";
                LogModel.Status = WorkStationStatus.Aborted;
                throw;
            }
            catch (Exception)
            {
                LogModel.LogInfo = $"{axis.ControlName}相对移动异常!";
                LogModel.Status = WorkStationStatus.Aborted;
                throw;
            }

            return res;

        }

        public async Task<(bool, short, string)> RelMoveAsync(IMotion axis, double point)
        {
            StepPause();

            (bool, short, string) res = (true, 0, "done");

            try
            {
                await IsSaftyToMove();
                res = IsAxisReady(axis);

                IsMovingPosOutofRange(axis, point, false);

                await Task.Run(async () =>
                {
                    try
                    {
                        PauseEventSource.WaitOne();
                        LogModel.LogInfo = $"{axis.ControlName}开始相对移动：{point}";

                        res = await axis.RelMoveAsync(point, cancellationToken, PauseEventSource);
                    }
                    catch (TaskCanceledException)
                    {
                        // 在这里处理取消操作，如果需要
                        LogModel.LogInfo = $"{axis.ControlName}点动被中断!";
                        LogModel.Status = WorkStationStatus.Aborted;
                        throw; // 重新抛出异常以将其传播到Task.Run之外
                    }


                }, cancellationToken);
                PauseEventSource.WaitOne();
                if (!res.Item1)
                {
                    SetAllAxisStop();
                    LogModel.LogInfo = $"{res.Item3}";
                    LogModel.Status = WorkStationStatus.Aborted;
                    throw new MyAxisException(res.Item3);
                }

                LogModel.LogInfo = $"{axis.ControlName}相对移动：{point}";
            }
            catch (OperationCanceledException)
            {
                // 取消请求被捕获，可以在这里进行相应的清理工作
                LogModel.LogInfo = $"{axis.ControlName}相对移动被中断!";
                LogModel.Status = WorkStationStatus.Aborted;
                throw;
            }
            catch (MyAxisException ex)
            {
                LogModel.LogInfo = $"{ex.Message}";
                LogModel.Status = WorkStationStatus.Aborted;
                throw;
            }
            catch (Exception)
            {
                LogModel.LogInfo = $"{axis.ControlName}相对移动异常!";
                LogModel.Status = WorkStationStatus.Aborted;
                throw;
            }

            return res;

        }

        public async Task<(bool, short, string)> JogMoveAsync(IMotion axis, ushort dir)
        {

            (bool, short, string) res = (true, 0, "done");

            try
            {
                await IsSaftyToMove();
                res =  IsAxisReady(axis);

                PauseEventSource.WaitOne();
                LogModel.LogInfo = $"{axis.ControlName}开始{dir}点动";

                res.Item2 = axis.Jog(dir);

                LogModel.LogInfo = $"{axis.ControlName} 点动中...";
            }
            catch (OperationCanceledException)
            {
                // 取消请求被捕获，可以在这里进行相应的清理工作
                LogModel.LogInfo = $"{axis.ControlName}点动被中断!";
                LogModel.Status = WorkStationStatus.Aborted;
                throw;
            }
            catch (MyAxisException ex)
            {
                LogModel.LogInfo = $"{ex.Message}";
                LogModel.Status = WorkStationStatus.Aborted;
                throw;
            }
            catch (Exception)
            {
                LogModel.LogInfo = $"{axis.ControlName}点动异常!";
                LogModel.Status = WorkStationStatus.Aborted;
                throw;
            }
            return res;

        }

           
        public async Task<(bool, short, string)> BasingAsync(IValve valve)
        {
            StepPause();

            (bool, short, string) res = (true, 0, "done");

            try
            {
                PauseEventSource.WaitOne();

                if (cancellationToken.IsCancellationRequested)
                {
                    cancellationToken.ThrowIfCancellationRequested();
                }


                LogModel.LogInfo = $"{valve.ValveName}开始去原位！";

                while (true)
                {
                    try
                    {
                        res.Item1 = await valve.BasingAsync();
                        if (res.Item1)
                        {
                            break;
                        }
                    }
                    catch (ValveException)
                    {
                        PauseEvent?.Invoke();
                        var retryRes = (MessageBoxResult)(RetryEvent?.Invoke($"{valve.ValveName}去原位超时，请检查地址：I{valve.BaseInAddress}，是否重试？"))!;
                        Logger.Error($"{valve.ValveName}去原位超时，地址：I{valve.WorkInAddress}");
                        if (retryRes == MessageBoxResult.Yes)
                        {
                            LogModel.LogInfo = $"{valve.ValveName}去原位超时，重试中...";
                        }
                        else if (retryRes == MessageBoxResult.No)
                        {
                            LogModel.LogInfo = $"{valve.ValveName}去原位超时，放弃重试。";
                            StopTrigger(isSetAbortedStatus: false);
                            res = (false, 1, "Basing timeOut");
                            break;
                        }
                        else
                        {
                            throw new InvalidOperationException("Unexpected MessageBoxResult");
                        }
                    }
                }

                LogModel.LogInfo = $"{valve.ValveName}去原位完成！";
            }
            catch (OperationCanceledException)
            {
                LogModel.LogInfo = $"{valve.ValveName}去原位被中断！";
                LogModel.Status = WorkStationStatus.Aborted;
                throw;
            }
            catch (Exception ex)
            {
                // 处理其他可能的异常
                LogModel.LogInfo = $"{valve.ValveName}去原位过程中发生异常: {ex.Message}";
                res = (false, 1, "Basing failed due to exception");
            }

            return res;
        }


        public async Task<(bool, short, string)> WorkingAsync(IValve valve)
        {
            StepPause();

            (bool, short, string) res = (true, 0, "done");

            try
            {
                PauseEventSource.WaitOne();
                if (cancellationToken.IsCancellationRequested)
                {
                    cancellationToken.ThrowIfCancellationRequested();
                }

                LogModel.LogInfo = $"{valve.ValveName}开始去工作位！";

                while (true)
                {
                    try
                    {
                        res.Item1 = await valve.WorkingAsync();
                        if (res.Item1)
                        {
                            break;
                        }
                    }
                    catch (ValveException e)
                    {
                        
                        PauseEvent?.Invoke();
                        var retryRes = (MessageBoxResult)(RetryEvent?.Invoke($"{valve.ValveName}去工作位超时，请检查地址：I{valve.WorkInAddress}，是否重试？"))!;
                        Logger.Error(e,$"{valve.ValveName}去工作位超时，地址：I{valve.WorkInAddress}");

                        if (retryRes == MessageBoxResult.Yes)
                        {
                            LogModel.LogInfo = $"{valve.ValveName}去工作位超时，重试中...";
                        }
                        else if (retryRes == MessageBoxResult.No)
                        {
                            LogModel.LogInfo = $"{valve.ValveName}去工作位超时，放弃重试。";
                            StopTrigger(isSetAbortedStatus: false);
                            res = (false, 1, "Working timeOut");
                            break;
                        }
                        else
                        {
                            throw new InvalidOperationException("Unexpected MessageBoxResult");
                        }
                    }
                }

                LogModel.LogInfo = $"{valve.ValveName}去工作位完成！";
            }
            catch (OperationCanceledException)
            {
                
                LogModel.LogInfo = $"{valve.ValveName}去工作位被中断！";
                LogModel.Status = WorkStationStatus.Aborted;
                throw;
            }
            catch (Exception ex)
            {
                // 处理其他可能的异常
                LogModel.LogInfo = $"{valve.ValveName}去工作位过程中发生异常: {ex.Message}";
                res = (false, 1, "Working failed due to exception");
            }

            return res;
        }


        public async Task<(bool, short, string)> ContiImpLineRelMoveAsync(IImputation axises, params PointSettingModel[] points)
        {
            StepPause();

            (bool, short, string) res = (true, 0, "done");

            try
            {
                await IsSaftyToMove();

                //  IsMovingPosOutofRange(axis, point, false);

                await Task.Run(async () =>
                {
                    try
                    {
                        PauseEventSource.WaitOne();
                        LogModel.LogInfo = $"{axises.ControlName}开始连续直线插补绝对移动相对移动：{axises.ControlName}";

                        List<double> targetPoints = new List<double>();
                        foreach (var point in points)
                        {
                            targetPoints.Add(point.Parameter);
                        }

                        res = await axises.ContiImpLineRelMoveAsync(targetPoints.ToArray(),0, cancellationToken, PauseEventSource);
                        PauseEventSource.WaitOne();
                    }
                    catch (TaskCanceledException)
                    {
                        // 在这里处理取消操作，如果需要
                        LogModel.LogInfo = $"{axises.ControlName}连续直线插补相对移动被中断!";
                        LogModel.Status = WorkStationStatus.Aborted;
                        throw; // 重新抛出异常以将其传播到Task.Run之外
                    }


                }, cancellationToken);

                LogModel.LogInfo = $"{axises.ControlName}相对移动：{axises.ControlName}";
            }
            catch (OperationCanceledException)
            {
                // 取消请求被捕获，可以在这里进行相应的清理工作
                LogModel.LogInfo = $"{axises.ControlName}连续直线插补相对移动被中断!";
                LogModel.Status = WorkStationStatus.Aborted;
                throw;
            }
            catch (MyAxisException ex)
            {
                LogModel.LogInfo = $"{ex.Message}";
                LogModel.Status = WorkStationStatus.Aborted;
                throw;
            }
            catch (Exception)
            {
                LogModel.LogInfo = $"{axises.ControlName}连续直线插补相对移动异常!";
                LogModel.Status = WorkStationStatus.Aborted;
                throw;
            }

            return res;
        }


        public async Task<(bool, short, string)> ContiImpLineRelMoveAsync(IImputation axises, params double[] points)
        {
            StepPause();

            (bool, short, string) res = (true, 0, "done");

            try
            {
                await IsSaftyToMove();

                //  IsMovingPosOutofRange(axis, point, false);

                await Task.Run(async () =>
                {
                    try
                    {
                        PauseEventSource.WaitOne();
                        LogModel.LogInfo = $"{axises.ControlName}开始连续直线插补绝对移动相对移动：{axises.ControlName}";

                        List<double> targetPoints = new List<double>();
                        foreach (var point in points)
                        {
                            targetPoints.Add(point);
                        }

                        res = await axises.ContiImpLineRelMoveAsync(targetPoints.ToArray(), 0, cancellationToken, PauseEventSource);
                        PauseEventSource.WaitOne();
                    }
                    catch (TaskCanceledException)
                    {
                        // 在这里处理取消操作，如果需要
                        LogModel.LogInfo = $"{axises.ControlName}连续直线插补相对移动被中断!";
                        LogModel.Status = WorkStationStatus.Aborted;
                        throw; // 重新抛出异常以将其传播到Task.Run之外
                    }


                }, cancellationToken);

                LogModel.LogInfo = $"{axises.ControlName}相对移动：{axises.ControlName}";
            }
            catch (OperationCanceledException)
            {
                // 取消请求被捕获，可以在这里进行相应的清理工作
                LogModel.LogInfo = $"{axises.ControlName}连续直线插补相对移动被中断!";
                LogModel.Status = WorkStationStatus.Aborted;
                throw;
            }
            catch (MyAxisException ex)
            {
                LogModel.LogInfo = $"{ex.Message}";
                LogModel.Status = WorkStationStatus.Aborted;
                throw;
            }
            catch (Exception)
            {
                LogModel.LogInfo = $"{axises.ControlName}连续直线插补相对移动异常!";
                LogModel.Status = WorkStationStatus.Aborted;
                throw;
            }

            return res;
        }



        public async Task<(bool, short, string)> ContiImpLineAbsMoveAsync(IImputation axises, params PointSettingModel[] points)
        {
            StepPause();

            (bool, short, string) res = (true, 0, "done");

            try
            {
                await IsSaftyToMove();

                //  IsMovingPosOutofRange(axis, point, false);

                await Task.Run(async () =>
                {
                    try
                    {
                        PauseEventSource.WaitOne();
                        LogModel.LogInfo = $"{axises.ControlName}开始连续直线插补绝对移动：{axises.ControlName}";

                        List<double> targetPoints = new List<double>();
                        foreach (var point in points)
                        {
                            targetPoints.Add(point.Parameter);
                        }

                        res = await axises.ContiImpLineAbsMoveAsync(targetPoints.ToArray(), 0, cancellationToken, PauseEventSource);
                        PauseEventSource.WaitOne();
                    }
                    catch (TaskCanceledException)
                    {
                        // 在这里处理取消操作，如果需要
                        LogModel.LogInfo = $"{axises.ControlName}开始连续直线插补绝对移动被中断!";
                        LogModel.Status = WorkStationStatus.Aborted;
                        throw; // 重新抛出异常以将其传播到Task.Run之外
                    }


                }, cancellationToken);

                LogModel.LogInfo = $"{axises.ControlName}相对移动：{axises.ControlName}";
            }
            catch (OperationCanceledException)
            {
                // 取消请求被捕获，可以在这里进行相应的清理工作
                LogModel.LogInfo = $"{axises.ControlName}开始连续直线插补绝对移动被中断!";
                LogModel.Status = WorkStationStatus.Aborted;
                throw;
            }
            catch (MyAxisException ex)
            {
                LogModel.LogInfo = $"{ex.Message}";
                LogModel.Status = WorkStationStatus.Aborted;
                throw;
            }
            catch (Exception)
            {
                LogModel.LogInfo = $"{axises.ControlName}开始连续直线插补绝对移动异常!";
                LogModel.Status = WorkStationStatus.Aborted;
                throw;
            }

            return res;
        }



        public async Task<(bool, short, string)> ContiImpLineAbsMoveAsync(IImputation axises, params double[] points)
        {
            StepPause();

            (bool, short, string) res = (true, 0, "done");

            try
            {
                await IsSaftyToMove();

                //  IsMovingPosOutofRange(axis, point, false);

                await Task.Run(async () =>
                {
                    try
                    {
                        PauseEventSource.WaitOne();
                        LogModel.LogInfo = $"{axises.ControlName}开始连续直线插补绝对移动：{axises.ControlName}";

                        List<double> targetPoints = new List<double>();
                        foreach (var point in points)
                        {
                            targetPoints.Add(point);
                        }

                        res = await axises.ContiImpLineAbsMoveAsync(targetPoints.ToArray(), 0, cancellationToken, PauseEventSource);
                        PauseEventSource.WaitOne();
                    }
                    catch (TaskCanceledException)
                    {
                        // 在这里处理取消操作，如果需要
                        LogModel.LogInfo = $"{axises.ControlName}开始连续直线插补绝对移动被中断!";
                        LogModel.Status = WorkStationStatus.Aborted;
                        throw; // 重新抛出异常以将其传播到Task.Run之外
                    }


                }, cancellationToken);

                LogModel.LogInfo = $"{axises.ControlName}相对移动：{axises.ControlName}";
            }
            catch (OperationCanceledException)
            {
                // 取消请求被捕获，可以在这里进行相应的清理工作
                LogModel.LogInfo = $"{axises.ControlName}开始连续直线插补绝对移动被中断!";
                LogModel.Status = WorkStationStatus.Aborted;
                throw;
            }
            catch (MyAxisException ex)
            {
                LogModel.LogInfo = $"{ex.Message}";
                LogModel.Status = WorkStationStatus.Aborted;
                throw;
            }
            catch (Exception)
            {
                LogModel.LogInfo = $"{axises.ControlName}开始连续直线插补绝对移动异常!";
                LogModel.Status = WorkStationStatus.Aborted;
                throw;
            }

            return res;
        }



        #endregion


        #region WorkFlow

        public abstract Task DryRun();

        public abstract Task Initial();
    
        public abstract Task Execute();

        /// <summary>
        /// 复位错误
        /// </summary>
        /// <returns></returns>
        public async Task<(bool, short, string)> Reset()
        {
            IsReady = false;
            IsDone = false;

            foreach (var robotModel in RobotModels)
            {
                await robotModel.Robot.ResetAsync();
            }

            if (LogModel.Status.Equals(WorkStationStatus.Aborted))
            {
                LogModel.Status = WorkStationStatus.Stopped;
            }

            if (AxisModels.Count <= 0)
            {
                LogModel.LogInfo = "复位完成";               
                return (true, 0, "Axis reset Done");
            }
            foreach (var axis in AxisModels)
            {
                axis.MotionEntity?.Reset();
            }
            await Task.Delay(100);

            LogModel.LogInfo = "复位完成";
           
            return (true, 0, "Axis reset Done");

        }

        /// <summary>
        /// 暂停
        /// </summary>
        public async Task Pause()
        {
            PauseEventSource.Reset();

            waitInputEvent.Reset();

            SetAllAxisPause();

            await SetAllRobotPause();

            GetAllAxesAndValveStatus();

            LogModel.Status = WorkStationStatus.Held;
        }




        /// <summary>
        /// 恢复运行
        /// </summary>
        public async Task  Resume()
        {
            LogModel.Status = WorkStationStatus.Execute;

            waitInputEvent.Set();

            await SetAllAxisResume();
            await SetAllRobotResume();     
            
            PauseEventSource.Set();
          
           // LogModel.Status = WorkStationStatus.Execute;
        }

        public void NextStep()
        {
            SingleStepCompleteEvent.Set();
        }


        public  void StepPause()
        {
            if (IsStepMode)
            {
                
                SingleStepCompleteEvent.Reset();
                LogModel.Status = WorkStationStatus.Completed;
                SingleStepCompleteEvent.WaitOne();
            }
           
        }

        public async Task StepPauseAsync()
        {
            if (IsStepMode)
            {
                await Task.Run(() =>
                {
                    SingleStepCompleteEvent.Reset();
                    LogModel.Status = WorkStationStatus.Completed;
                    SingleStepCompleteEvent.WaitOne();
                });
            }

        }


        /// <summary>
        /// 缺料报警
        /// </summary>
        public void Shortage()
        {
            LogModel.LogInfo = $"{StationName}:缺料！";
            LogModel.Status = WorkStationStatus.Held;
        }

        public async Task Stop(string? stopMessage = null,bool isSetAbortedStatus = true)
        {
            try
            {
               
               isDone = false;
                isReady = false;
                foreach (var robotModel in RobotModels)
                {
                    await robotModel.Robot.StopAsync();
                }

                SetAllAxisStop();

                StationStop();

                waitInputEvent.Set();

                if (!cancellationToken.IsCancellationRequested)
                {
                    this.CancellationTokenSource?.Cancel();
                    CancellationTokenSource?.Dispose();
                }
                if (stopMessage != null)
                {
                    LogModel.LogInfo = stopMessage;
                }

                PauseEventSource.Set();
                SingleStepCompleteEvent.Set();
                if (isSetAbortedStatus)
                {
                    LogModel.Status = WorkStationStatus.Aborted;
                }
               
            }
            catch (Exception)
            {

                throw;
            }
            finally
            {
               // PauseEventSource.Dispose();
               CancellationTokenSource?.Dispose();
            }
            
          
        }

        public abstract Task Clear(bool isClear);
        public abstract void RegisterEvent();

        public abstract Task Test();

        public abstract Task  ResetSignal();


        public abstract void StationStop();

        /// <summary>
        /// 暂停时记录轴和气缸的当前状态
        /// </summary>
        public void GetAllAxesAndValveStatus()
        {
            AxesPausePosition.Clear();
            foreach (var axis in AxisModels)
            {
                if (axis.MotionEntity is null)
                {
                    continue;
                }
                AxesPausePosition.Add(axis.MotionEntity.ControlName, axis.MotionEntity.ActualPosition);
                                
            }

            ValvesPauseStatus.Clear();
            foreach (var valve in CylinderModels)
            {
                if (valve.ValveEntity is null)
                {
                    continue;
                }

                ValvesPauseStatus.Add(valve.ValveEntity.ValveName, valve.ValveEntity.WorkIn);
            }


            RobotsPauseStatus.Clear();
            foreach (var robot in RobotModels)
            {
                if (robot is null)
                {
                    continue;
                }

                RobotsPauseStatus.Add(robot.Robot.ControlName, robot.Robot.RobotPositionModel);
            }

        }


        /// <summary>
        /// 暂停恢复，检查轴和气缸是否在暂停前状态
        /// </summary>
        /// <returns></returns>
        public (bool,string,string) ResumnBeforeCheckStatus()


        {

            //检查轴是否在安全位置
            if (AxesPausePosition.Count>0)
            {
                foreach (var axis in AxisModels)
                {
                    if (axis.MotionEntity is null)
                    {
                        continue;
                    }

                    // 检查 AxesPausePosition 是否包含与 axis.MotionEntity.ControlName 相同的 key
                    if (AxesPausePosition.TryGetValue(axis.MotionEntity.ControlName, out var pausePositionValue))
                    {
                        // 如果存在相同的 key，检查它们的 value 是否一致
                        if (Math.Abs(axis.MotionEntity.ActualPosition - pausePositionValue)>1)
                        {
                            return (false, axis.MotionEntity.ControlName, axis.MotionEntity.ActualPosition.ToString());
                        }
                        
                    }

                }
            }


            //检查气缸是否在安全位置

            if (ValvesPauseStatus.Count>0)
            {
                foreach (var valve in CylinderModels)
                {
                    if (valve.ValveEntity is null)
                    {
                        continue;
                    }

                    // 检查 AxesPausePosition 是否包含与 axis.MotionEntity.ControlName 相同的 key
                    if (ValvesPauseStatus.TryGetValue(valve.ValveEntity.ValveName, out var pauseValue))
                    {
                        // 如果存在相同的 key，检查它们的 value 是否一致
                        if (valve.ValveEntity.WorkIn != pauseValue)
                        {
                            return (false, valve.ValveEntity.ValveName, pauseValue.ToString());
                        }

                    }
                }
            }


            //检查机器人是否在安全位置

            if (RobotsPauseStatus.Count > 0)
            {
                foreach (var robot in RobotModels)
                {
                    if (robot is null)
                    {
                        continue;
                    }

                    // 检查 AxesPausePosition 是否包含与 axis.MotionEntity.ControlName 相同的 key
                    if (RobotsPauseStatus.TryGetValue(robot.Robot.ControlName, out var pauseValue))
                    {
                        // 将 pauseValue 转换为 RobotPositionModel 类型
                        if (pauseValue is RobotPositionModel pausePosition)
                        {
                            // 获取所有属性名
                            var properties = typeof(RobotPositionModel).GetProperties();

                            foreach (var property in properties)
                            {
                                var currentValue = property.GetValue(robot.Robot.RobotPositionModel);
                                var pauseValueProperty = property.GetValue(pausePosition);

                               
                                // 比较属性值
                                if (currentValue != null && pauseValueProperty != null && Math.Abs((double)currentValue - (double)pauseValueProperty) >=1)
                                {
                                    double value = (double)currentValue;
                                    return (false, robot.Robot.ControlName, value.ToString());
                                }
                            }
                        }

                    }
                }
            }


            return (true,string.Empty, string.Empty);
        }

        #endregion


        #region Utility

        public PointSettingModel[] DoubleToPoint(params double[] doubles)
        {
            List<PointSettingModel> Points = new List<PointSettingModel>(); 
            foreach (double item in doubles)
            {
                PointSettingModel pointSettingModel = new PointSettingModel() { Parameter = item };
                Points.Add(pointSettingModel);
            }
            return Points.ToArray();
        }

        #endregion


        #region Request Event

        /// <summary>
        /// 发送请求
        /// </summary>
        /// <param name="request">请求信息</param>
        /// <returns></returns>
        public async Task<bool> SendAsync(EventBase? request)
        {
            try
            {
                PauseEventSource.WaitOne();
                if (request is null)
                {
                    return false;
                }

                Logger.Debug($"MessageType:{request.MessageType.ToString()},Message:{request.Message}");

                await EventAggregator.PublishOnUIThreadAsync(request);
                return await request.TaskCompletionSource.Task;
            }
            catch (Exception)
            {

                throw;
            }
            
        }

        public void Send(EventBase? request)
        {
            try
            {
                PauseEventSource.WaitOne();
                if (request is null)
                {
                    return;
                }

                Logger.Debug($"MessageType:{request.MessageType.ToString()},Message:{request.Message}");

                 EventAggregator.PublishOnUIThreadAsync(request);
                
            }
            catch (Exception)
            {

                throw;
            }

        }


        /// <summary>
        /// 处理请求信息
        /// </summary>
        /// <param name="message">请求信息</param>
        /// <returns></returns>
        public  Task RequestHandle(EventBase message)
        {
            if (message.MessageType == MessageType.RequestReady)
            {
                message.TaskCompletionSource.SetResult(isReady || IsShield);
                
            }
            else if (message.MessageType == MessageType.RequestDone)
            {
                message.TaskCompletionSource.SetResult(isDone || IsShield);
            }
            else if (message.MessageType == MessageType.RequestReadyOrDone)
            {
                message.TaskCompletionSource.SetResult(isDone || isReady || IsShield);
            }
            else if (message.MessageType == MessageType.ResetReady)
            {
                isReady = false;
                message.TaskCompletionSource.SetResult(true);
            }
            else if (message.MessageType == MessageType.ResetDone)
            {
                isDone = false;
                message.TaskCompletionSource.SetResult(true);
            }

            return Task.CompletedTask;
        }


        public bool IsRequest(EventBase message)
        {
            if (message.MessageType.ToString().Contains("Request") || message.MessageType.ToString().Contains("Reset"))
            {
                return true;
            }

            return false;
        }


        public bool IsActionNotify(EventBase nofity)
        {
           // nofity.TaskCompletionSource.SetResult(true);
            return nofity.MessageType == MessageType.NotifyAction;
        }
        public bool IsReadyNotify(EventBase nofity)
        {
           // nofity.TaskCompletionSource.SetResult(true);
            return nofity.MessageType == MessageType.NotifyReady;
        }

        public bool IsTrayEmptyNotify(EventBase nofity)
        {
          //  nofity.TaskCompletionSource.SetResult(true);
            return nofity.MessageType == MessageType.NotifyTrayEmpty;
        }

        public bool IsTrayNotEmptyNotify(EventBase nofity)
        {
           // nofity.TaskCompletionSource.SetResult(true);
            return nofity.MessageType == MessageType.NotifyTrayNotEmpty;
        }
        public bool IsTrayFullNotify(EventBase nofity)
        {
           // nofity.TaskCompletionSource.SetResult(true);
            return nofity.MessageType == MessageType.NotifyTrayFull;
        }


        public bool IsDoneNotify(EventBase nofity)
        {
           // nofity.TaskCompletionSource.SetResult(true);
            return nofity.MessageType == MessageType.NotifyDone;
        }

        public bool IsActionDoneNotify(EventBase nofity)
        {
           // nofity.TaskCompletionSource.SetResult(true);
            return nofity.MessageType == MessageType.AcitonDone;
        }

       
        public bool IsReadyOrDoneNotify(EventBase nofity)
        {
            nofity.TaskCompletionSource.SetResult(true);
            return nofity.MessageType == MessageType.NotifyDone || nofity.MessageType == MessageType.NotifyReady;
        }


        

       

        #endregion
    }
}
